<template>
    <div class="ai-layout">
        <div class="btn-ai"
             :style="btnStyle"
             @mousedown="startDrag"
             @mouseup="handleClick"
             ref="draggableBtn">
            <img src="./style/images/log.png" class="ai-logo" alt="ai-logo" @dragstart.prevent>
        </div>
        <a-modal :open="open" :width="modalStyle.width"  @cancel="handleCancel" :footer="null" >
            <template #title>
                <div ref="modalTitleRef" class="drag-header">
                    <span>{{ imgTitle }}</span>
                </div>
                <div class="header-actions">
                    <a-tooltip :title="isFullscreen ? '退出全屏宽度' : '全屏宽度'">
                        <FullscreenOutlined  @click="toggleFullscreen"/>
                    </a-tooltip>
                </div>
            </template>
            <!-- 修改modalRender部分 -->
            <template #modalRender="{ originVNode }">
                <div :style="transformStyle">
                    <component :is="originVNode" />
                </div>
            </template>
            <div class="ai-chat-container" :style="{height:modalStyle.height}">
                <!-- 消息区域 -->
                <div class="message-wrapper-layout">
                    <div class="welcome-card">
                        <div class="welcome-icon">
                            <img src="./style/images/fmt.webp" alt="icon">
                        </div>
                        <div class="welcome-content-wrapper">
                            <h4 class="welcome-title">{{ title }}</h4>
                            <span class="welcome-description">
                                {{ welcomeDescription }}
                            </span>
                        </div>
                    </div>
                    <!-- 添加滚动容器引用 -->
                    <div class="message-wrapper" ref="messageContainer">
                        <!-- 消息内容 -->
                        <div v-for="(msg, index) in messages" :key="index" :class="['message-bubble', msg.role]">
                            <div class="content">
                                <div v-if="msg.role === 'ai'" class="custom-markdown">
                                    <div v-html="parseMarkdown(msg.content.replace(/<\/?think>/g, ''))"></div>
                                </div>
                                <template v-else>{{ msg.content }}</template>
                                <slot :content="msg.content" :end="msg.end" :close="handleCancel"></slot>
                            </div>
                        </div>
                        <div class="append-tip" v-if="suggestedQuestions.length > 0">
                            <div class="append-tip_title">试着问问</div>
                            <div class="append-tip_group">
                                <div v-for="(question, index) in suggestedQuestions" :key="index" class="prompts-tip"
                                     @click="handleSuggestedQuestion(question)">
                                    <span>{{ question }}</span>
                                    <span class="tip-next">
                                    </span>
                                </div>
                            </div>
                            <!-- 加载状态 -->
                            <div v-if="loadingSuggestions" class="loading-suggestions">
                                正在加载建议问题...
                            </div>
                        </div>
                    </div>

                    <div v-if="loading" class="loading-wave">
                        <div class="wave-dot"></div>
                        <div class="wave-dot"></div>
                        <div class="wave-dot"></div>
                    </div>
                </div>

                <!-- 输入区域 -->
                <div class="input-layout">
                    <div class="input-tip" v-if="promptList.length > 0">
                        <section class="input-tip_item" @click="handlePrompts(item.label)"
                                 v-for="(item, key) in promptList" :key="key">
                            <div class="item-prompts_icon">
                                <img :src="item.icon" alt="icon"/>
                            </div>
                            <div class="item-prompts_content">
                                <p class="prompts-desc">{{ item.label }}?</p>
                            </div>
                        </section>
                    </div>
                    <div class="input-area">
                        <a-input v-model:value="inputMessage" placeholder="输入你的问题..."
                                 @pressEnter="()=>sendMessage()"
                                 class="sci-input">
                            <template #suffix>
                                <a-tooltip title="停止生成" v-if="isStop">
                                    <div @click="stopMessage" class="stop-btn">
                                        <StopOutlined/>
                                    </div>
                                </a-tooltip>
                                <a-tooltip title="发送" v-else>
                                    <div @click="()=>sendMessage()" class="send-btn">
                                        <ArrowUpOutlined/>
                                    </div>
                                </a-tooltip>
                            </template>
                        </a-input>
                    </div>
                </div>
            </div>
        </a-modal>
    </div>

</template>
<script setup>
import {defineProps, nextTick, reactive, ref, watch, onMounted, onUnmounted} from 'vue';
import light from './style/images/light-up.svg'
import flame from './style/images/flame.svg'
import books from './style/images/books.svg'
import {parseMarkdown} from './config/markdown-config'
import {message} from 'ant-design-vue';
import initDraggable from "./config/modal-drag";
import {useBtnDrag} from './config/btn-drag';

const props = defineProps({
    imgTitle: {
        type: String,
        default: "AI助手"
    },
    title: {
        type: String,
        default: "Hello, 我是红迅Ai助手"
    },
    welcomeDescription: {
        type: String,
        default: "有关知识库的问题都可以向我提问~"
    },
    incomingInfo: {
        type: String,
        default: "我是智能ai助手"
    },
    chatMessage: {
        type: Object,
        default: {
            url: "http://dev.redxun.cn:8088/v1/chat-messages",
            header: {
                Authorization: "Bearer app-1YjlZu6yW4hr1K03v0qLbAcV",
            },
            body: {
                response_mode: "streaming",
                user: "abc-123",
                inputs: {},
            }
        }
    },
    promptList: {
        type: Array,
        default: [
            {
                label: "怎么使用知识库",
                icon: light
            },
            {
                label: "最热门问题",
                icon: flame
            },
            {
                label: "你是谁",
                icon: books
            },
        ]
    },
    questions: {
        type: Array,
        default: () => []
    }
});
const emits = defineEmits(['fetchSuggestedQuestions', 'openParamsChange']);

const open = ref(false);

const inputMessage = ref('');
// 上一次回话id
const conversationId = ref('')
const messages = reactive([]);
const loading = ref(false);
const isStop = ref(false)
const currentAiMessage = ref(null);
const controller = ref(null);
// 下一步状态
const suggestedQuestions = ref([])
const loadingSuggestions = ref(false)
const currentMessageId = ref(null)

// 消息容器引用
const messageContainer = ref(null)
// 初始化拖拽并获取返回值
const isFullscreen = ref(false);
const {transformStyle, modalTitleRef, transformX, transformY} = initDraggable(isFullscreen);
const modalStyle = reactive({
    width: '720px',
})
// 修改后的全屏切换方法
const toggleFullscreen = () => {
    if (!isFullscreen.value) {
        // 进入全屏时保存原始位置
        localStorage.setItem('originalTransform', JSON.stringify({
            x: transformX.value,
            y: transformY.value
        }));
        modalStyle.width = '100vw';
    } else {
        // 退出时恢复位置
        const original = JSON.parse(localStorage.getItem('originalTransform'));
        transformX.value = original.x;
        transformY.value = original.y;
        modalStyle.width = '720px';
    }
    isFullscreen.value = !isFullscreen.value;
};
// 自动滚动到底部
const scrollToBottom = () => {
    nextTick(() => {
        if (messageContainer.value) {
            messageContainer.value.scrollTop = messageContainer.value.scrollHeight
        }
    })
}

// 修改processAnswerContent函数
const processAnswerContent = (content) => {
    // 保留think标签用于后续解析
    return content
        .replace(/\\n/g, '\n')
        .replace(/\\t/g, '\t')
        .replace(/\\"/g, '"');
};

const handleMessageEvent = (eventData) => {
    if (eventData.answer) {
        currentAiMessage.value.content += processAnswerContent(eventData.answer);
        // 确保解析内容包含think标签
        currentAiMessage.value.parsedContent = currentAiMessage.value.content;
        scrollToBottom();
    }
};
const sendMessage = async (externalQuery) => {
    try {
        inputMessage.value = externalQuery || inputMessage.value
        if (!inputMessage.value.trim()) {
            message.warning('请输入有效内容')
            return
        }

        // 中止之前的请求
        if (controller.value) {
            controller.value.abort()
        }
        // 立即清空输入框
        const tempInput = inputMessage.value; // 保存原始值用于请求
        inputMessage.value = '';  // 立即清空输入框
        // 添加用户消息
        messages.push({
            role: 'user',
            content: tempInput
        })

        // 创建并存储AI消息
        currentAiMessage.value = {
            role: 'ai',
            content: '',
            allMessage: '',
            /*消息是否回答完成*/
            end: false,
        }
        messages.push(currentAiMessage.value)

        loading.value = true;
        isStop.value = true;

        // 使用AbortController控制请求
        controller.value = new AbortController();

        const response = await fetch(props.chatMessage.url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                ...props.chatMessage.header
            },
            body: JSON.stringify({
                query: tempInput,
                conversation_id: conversationId.value,
                ...props.chatMessage.body
            }),
            signal: controller.value.signal
        });

        const reader = response.body.getReader();
        const decoder = new TextDecoder('utf-8');
        let buffer = '';

        while (true) {
            const {done, value} = await reader.read();
            if (done) break;

            buffer += decoder.decode(value, {stream: true});
            const chunks = buffer.split('\n\n');
            buffer = chunks.pop() || '';

            for (const chunk of chunks) {
                const lines = chunk.split('\n').filter(line => line.startsWith('data: '));
                for (const line of lines) {
                    try {
                        const rawData = line.replace('data: ', '');
                        currentAiMessage.value.allMessage += rawData;
                        const eventData = JSON.parse(rawData);

                        // 统一处理消息事件
                        if (['agent_message', 'message'].includes(eventData.event)) {
                            handleMessageEvent(eventData);
                        }

                        if (eventData.event === 'message_end') {
                            currentMessageId.value = eventData.message_id;
                            conversationId.value = eventData.conversation_id;
                        }
                    } catch (e) {
                        console.error('解析数据出错:', e);
                    }
                }
            }
        }
    } catch (error) {
        if (error.name !== 'AbortError') {
            message.error('请求失败: ' + error.message);
        }
    } finally {
        loading.value = false;
        isStop.value = false;
        controller.value = null;
        // 在消息处理完成后获取建议
        currentAiMessage.value.end = true;
        if (currentMessageId.value) {
            loadingSuggestions.value = true
            try {
                await emits('fetchSuggestedQuestions', currentMessageId.value)
            } finally {
                loadingSuggestions.value = false
            }
        }
        scrollToBottom()
    }
};


// 处理建议问题点击
const handleSuggestedQuestion = (question) => {
    inputMessage.value = question
    sendMessage();
    suggestedQuestions.value = [] // 清空当前建议
}

const stopMessage = () => {
    if (controller.value) {
        controller.value.abort();
    }
    isStop.value = false;
};

function handlePrompts(sendInfo) {
    inputMessage.value = sendInfo;
    sendMessage();
    suggestedQuestions.value = [] // 清空当前建议
}

function handleAi() {
    open.value = true;
    emits('openParamsChange')
}

function handleCancel() {
    open.value = false;
}

const {draggableBtn, btnStyle, startDrag, handleClick} = useBtnDrag(handleAi);
watch(
    () => props.incomingInfo,
    (newVal) => {
        if (newVal) {
            // 中止正在进行的请求
            if (controller.value) {
                controller.value.abort()
            }
            // 清空当前消息
            messages.splice(0, messages.length)
            // 触发新请求
            sendMessage(newVal)
        }
    },
)
// 添加监听器确保新消息创建时滚动
watch(() => messages.length, () => {
    scrollToBottom()
})
// 监听建议问题变化
watch(() => props.questions, (newVal) => {
    // 添加空值校验和数组类型校验
    if (Array.isArray(newVal) && newVal.length > 0) {
        suggestedQuestions.value = newVal;
        scrollToBottom()
    } else {
        suggestedQuestions.value = []; // 空值时重置为数组
    }
});


</script>
<style scoped lang="scss">
@import "style/ai-agent";
</style>
